//
// Created by lihengliu on 2023/3/4.
//

#ifndef JNIDEMO_JNI_STRING_CONVERT_UTIL_H
#define JNIDEMO_JNI_STRING_CONVERT_UTIL_H
#include <jni.h>
#include <string>

typedef struct JNIStringConvertUtil {
    //jstring转cstring
    static char *jstr2cstr(JNIEnv *env, jstring content) {
        char *result = nullptr;
        jclass clazz = env->FindClass("java/lang/String");
        jstring str_encode = env->NewStringUTF("UTF-8");
        jmethodID method_get_bytes = env->GetMethodID(clazz, "getBytes", "(Ljava/lang/String;)[B");
        auto byte_array = (jbyteArray) env->CallObjectMethod(content, method_get_bytes, str_encode);
        jsize byte_array_length = env->GetArrayLength(byte_array);
        jbyte *byte_array_bytes = env->GetByteArrayElements(byte_array, JNI_FALSE);
        if (byte_array_length > 0) {
            result = (char *) malloc(byte_array_length + 1);
            memcpy(result, byte_array_bytes, byte_array_length);
            result[byte_array_length] = 0;
        }
        env->ReleaseByteArrayElements(byte_array, byte_array_bytes, 0);
        return result;
    }

    static char *jstr2cstr(JNIEnv *env, const char *value) {
        char *result = nullptr;
        jstring content = env->NewStringUTF(value);
        jclass clazz = env->FindClass("java/lang/String");
        jstring str_encode = env->NewStringUTF("UTF-8");
        jmethodID method_get_bytes = env->GetMethodID(clazz, "getBytes", "(Ljava/lang/String;)[B");
        auto byte_array = (jbyteArray) env->CallObjectMethod(content, method_get_bytes, str_encode);
        jsize byte_array_length = env->GetArrayLength(byte_array);
        jbyte *byte_array_bytes = env->GetByteArrayElements(byte_array, JNI_FALSE);
        if (byte_array_length > 0) {
            result = (char *) malloc(byte_array_length + 1);
            memcpy(result, byte_array_bytes, byte_array_length);
            result[byte_array_length] = 0;
        }
        env->ReleaseByteArrayElements(byte_array, byte_array_bytes, 0);
        return result;
    }

    //c字符串转java字符串
    static jstring cstr2jstr(JNIEnv *env, const char *pat) {
        //定义java String类 strClass
        jclass strClass = (env)->FindClass("java/lang/String");
        //获取java String类方法String(byte[],String)的构造器,用于将本地byte[]数组转换为一个新String
        jmethodID ctorID = (env)->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
        //建立byte数组
        jbyteArray bytes = (env)->NewByteArray((jsize) strlen(pat));
        //将char* 转换为byte数组
        (env)->SetByteArrayRegion(bytes, 0, (jsize) strlen(pat), (jbyte *) pat);
        //设置String, 保存语言类型,用于byte数组转换至String时的参数
        jstring encoding = (env)->NewStringUTF("utf-8");
        //将byte数组转换为java String,并输出
        return (jstring) (env)->NewObject(strClass, ctorID, bytes, encoding);
    }

} StringConvert;
#endif //JNIDEMO_JNI_STRING_CONVERT_UTIL_H
